#include "simulator.h"

// generate requests for simulation
list<Request> Simulator::generateRequests(int num, int totalMem){

        srand(time(NULL));
        
        deque<Request> mallocs;
        deque<Request> frees;
        list<Request> final;

		int allocatedMem = 0;
	
	// generate allocations
        for(int i = 0; i < num; i++){
                // size = (1-10) * 2^(0-10) * 1024
                unsigned long size = (unsigned long)((rand() % 10 + 1) * pow(2.0, rand() % 11) * 1024);
                struct Request temp(i, size, 0);
                
                mallocs.push_back(temp);
        }
        // push allocations and corresponding frees to list
        while(!mallocs.empty()){
		// queue a request
                if( ((float)mallocs.size()/num > (float)rand()/RAND_MAX) && (allocatedMem + mallocs.size() < totalMem)){
                        //Copy the request twice, place it in the final queue, also in the queue for frees
                        struct Request tempFinal(mallocs.front());
                        struct Request tempFree(mallocs.front());
                        tempFree.type = 1;
                        final.push_back(tempFinal);
                        frees.push_back(tempFree);
                        
                        //shuffle the free queue
                        random_shuffle(frees.begin(), frees.end());     
                        
						allocatedMem += mallocs.front().size;
						
                        mallocs.pop_front();
                }
		// queue a free
                else{
                        if(!frees.empty()){
                                struct Request tempFinal(frees.front());
                                final.push_back(tempFinal);
                                
								allocatedMem -= frees.front().size;
								
                                frees.pop_front();                      
                        }               
                }       
        }
	
	// push remaining frees to list
        while(!frees.empty()){
                struct Request tempFinal(frees.front());
                final.push_back(tempFinal);
                
                frees.pop_front();      
        }
        
        return final;
}
